package org.jxf.gps.jt808.message;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.MessageEvent;
import org.jfk.core.utils.ByteUtils;
import org.jfk.core.utils.GeoPoint;
import org.jxf.gps.jfinal.model.MessageLog;
import org.jxf.gps.jt808.server.GpsServer;


public class MsgHandle {
	private static Logger logger = Logger.getLogger(MsgHandle.class);
	
	private byte[] recvBuff;
	private byte[] realBuff;
	private byte[] realResp;
	private byte[] sendResp;
	private Message msg;
	private Message respMsg;
	
	private MessageEvent messageEvent;
	
	public MsgHandle(MessageEvent e){
		this.messageEvent = e;
		ChannelBuffer buf = (ChannelBuffer) e.getMessage();
		int i = 0;
		List list = new ArrayList();
		while(buf.readable()){
			byte bt = buf.readByte();
			i++;
			list.add(bt);
		}
		
		recvBuff = new byte[i];
		for (int j = 0 ; j<list.size() ; j++){
			recvBuff[j] = (Byte)list.get(j);
		}
	}
	
	/**
	 * 检查是否包不全
	 * @return
	 */
	public boolean checkPkg(){
		if (recvBuff == null || recvBuff.length < 4){
			return false;
		}		
		if (recvBuff[0] != 0x7E){
			return false;
		}
		if (recvBuff[recvBuff.length - 1] != 0x7E){
			return false;
		}
		return true;
	}

	
	/**
	 * 将转义处理还原成0x7e或0x7d
	 */
	public void recoverMsg(){
		realBuff = MessageParser.recover7E7D(recvBuff);
	}
	
	public boolean checkCRC(){

		byte[] _head_body = new byte[realBuff.length - 3];
		System.arraycopy(realBuff, 1, _head_body, 0 , _head_body.length);
		if (ByteUtils.genCRC16(_head_body) != realBuff[realBuff.length - 2]){
			return false;
		}else{
			return true;
		}
	}
	

	
	/**
	 * 解析消息
	 */
	public void fillMsg(){
		msg = MessageParser.buf2msg(realBuff);
		msg.channelInfo = messageEvent.getChannel().getRemoteAddress().toString();
		msg.moTime = new Timestamp(System.currentTimeMillis());
	}
	
	/**
	 * 记录消息日志
	 */
	public void logMsg(Message msg){
		
		MessageLog log = new MessageLog();
		log.set("msgId", ByteUtils.intToWordString(msg.msgId)).
		set("mdn", msg.mdn).
		set("sn", msg.sn).
		set("createTime", new Timestamp(System.currentTimeMillis())).
		set("content", ByteUtils.byteToHexString(msg.body)).
		set("channelInfo", msg.channelInfo);
		GpsServer.dbQueue.add(log);
	}

	/**
	 * 发送回包
	 */
	public void sendResp(){
		byte[] resp = MessageParser.msg2buf(respMsg);
		ChannelBuffer cb = ChannelBuffers.wrappedBuffer(MessageParser.convert7E7D(resp)) ;
		messageEvent.getChannel().write(cb,messageEvent.getRemoteAddress());//兼容UDP，获取对端IP与端口。
	}
	
	public void handle() throws Exception {
		
		long t1 = System.currentTimeMillis();
		
		if (recvBuff == null || recvBuff.length ==0){
			return;
		}
		
		if (!this.checkPkg()){
			logger.error("包完整性错误");
			return;
		}
		
		recoverMsg();
		
		if (!this.checkCRC()){
			logger.error("CRC校验错误");
			//throw new Exception("CRC校验错误");
			return;
		}
		long t11 = System.currentTimeMillis();

		fillMsg();
		long t12 = System.currentTimeMillis();
		
		logMsg(msg);
		long t13 = System.currentTimeMillis();
		
		MsgBodyHandle handle = MsgBodyFactory.getMsgBodyHandle(msg.msgId);
		
		if (!handle.doMsg(msg)){
			messageEvent.getChannel().disconnect();
			messageEvent.getChannel().close();
			return;
		}
		
		long t14 = System.currentTimeMillis();
		
		respMsg = handle.genResp();

		if (respMsg != null){
			logMsg(respMsg);
			sendResp();
		}
		long t2 = System.currentTimeMillis();
		//logger.info("handle consume : "+(t2 - t1)+","+(t12 - t11)+","+(t13 - t12)+","+(t14 - t13)+","+(t2 - t14));
	}
}
